package com.estate.framework.web.service.data;


import com.estate.common.core.domain.model.ApiResponse;
import com.estate.common.core.domain.model.agent.AgentResp;
import com.estate.common.core.domain.model.contact.ContactResp;
import com.estate.common.core.domain.model.enquiry.EnquiryResp;
import com.estate.common.core.domain.model.listing.ListingResp;
import com.estate.common.utils.SnowflakeIdWorker;
import com.estate.system.domain.DataServiceRecord;
import com.estate.system.service.impl.DataServiceRecordServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

import static com.estate.common.utils.TimeZoneUtils.nowBeijingDateToSydneyDate;
import static com.estate.common.utils.TimeZoneUtils.nowBeijingToSydneyStr;

@Component
public class ZenuApiClient {
    private static final String BASE_URL = "https://api.zenu.com.au/api/v1";
    private static final String AUTH_ID = "8fwd62gabbya87plfp3lqpmhfgyxjpui";
    private static final String AUTH_TOKEN = "zg2ixmf4bslnrg8cpf3krvwyrfl4kvpm";

    private final OkHttpClient client;
    private final ObjectMapper objectMapper;
    private final String authorizationHeader;

    @Resource
    private DataServiceRecordServiceImpl dataServiceRecordServiceImpl;

    public ZenuApiClient() {
        this.client = new OkHttpClient();
        this.objectMapper = new ObjectMapper();
        this.authorizationHeader = generateAuthHeader();
    }

    private String generateAuthHeader() {
        String credentials = AUTH_ID + ":" + AUTH_TOKEN;
        String encodedCredentials = Base64.getEncoder().encodeToString(credentials.getBytes());
        return "Basic " + encodedCredentials;
    }

    /**
     * 基础获取房源列表
     */
    public ApiResponse<List<ListingResp>> getListings() throws IOException {
        return getListings(1, 2, null);
    }

    /**
     * 带分页和过滤条件的获取房源列表
     */
    public ApiResponse<List<ListingResp>> getListings(Integer pageNumber, Integer pageSize,
                                                      Map<String, String> filters) throws IOException {
        HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(BASE_URL + "/listings")).newBuilder();

        // 添加分页参数
        if (pageNumber != null) {
            urlBuilder.addQueryParameter("page[number]", pageNumber.toString());
        }
        if (pageSize != null) {
            urlBuilder.addQueryParameter("page[size]", pageSize.toString());
        }

        // 添加过滤条件
        if (filters != null) {
            for (Map.Entry<String, String> entry : filters.entrySet()) {
                urlBuilder.addQueryParameter("filter[" + entry.getKey() + "]", entry.getValue());
            }
        }

        Request request = new Request.Builder()
                .url(urlBuilder.build())
                .header("Authorization", authorizationHeader)
                .header("Content-Type", "application/json")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                assert response.body() != null;
                throw new IOException("Unexpected code: " + response + ", Body: " + response.body().string());
            }

            String responseBody = Objects.requireNonNull(response.body()).string();
            return objectMapper.readValue(responseBody,
                    objectMapper.getTypeFactory().constructParametricType(ApiResponse.class,
                            objectMapper.getTypeFactory().constructCollectionType(List.class, ListingResp.class)));
        }
    }

    /**
     * 根据ID获取单个房源详情
     */
    public ApiResponse<ListingResp> getListingById(Integer listingId) throws IOException {
        Request request = new Request.Builder()
                .url(BASE_URL + "/listings/" + listingId)
                .header("Authorization", authorizationHeader)
                .header("Content-Type", "application/json")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                assert response.body() != null;
                throw new IOException("Unexpected code: " + response + ", Body: " + response.body().string());
            }

            String responseBody = Objects.requireNonNull(response.body()).string();
            return objectMapper.readValue(responseBody,
                    objectMapper.getTypeFactory().constructParametricType(ApiResponse.class, ListingResp.class));
        }
    }


    /**
     * 搜索联系人
     */
    public ApiResponse<List<ContactResp>> searchContacts(Integer pageNumber, Integer pageSize,
                                                         Map<String, String> filters) throws IOException {
        HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(BASE_URL + "/contacts")).newBuilder();

        // 添加分页参数
        if (pageNumber != null) {
            urlBuilder.addQueryParameter("page[number]", pageNumber.toString());
        }
        if (pageSize != null) {
            urlBuilder.addQueryParameter("page[size]", pageSize.toString());
        }

        // 添加过滤条件
        if (filters != null) {
            for (Map.Entry<String, String> entry : filters.entrySet()) {
                urlBuilder.addQueryParameter("filter[" + entry.getKey() + "]", entry.getValue());
            }
        }

        Request request = new Request.Builder()
                .url(urlBuilder.build())
                .header("Authorization", authorizationHeader)
                .header("Content-Type", "application/json")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code: " + response + ", Body: " + Objects.requireNonNull(response.body()).string());
            }

            String responseBody = Objects.requireNonNull(response.body()).string();
            return objectMapper.readValue(responseBody,
                    objectMapper.getTypeFactory().constructParametricType(ApiResponse.class,
                            objectMapper.getTypeFactory().constructCollectionType(List.class, ContactResp.class)));
        }
    }

    /**
     * 根据ID获取单个联系人详情
     */
    public ApiResponse<ContactResp> getContactById(Integer contactId) throws IOException {
        Request request = new Request.Builder()
                .url(BASE_URL + "/contacts/" + contactId)
                .header("Authorization", authorizationHeader)
                .header("Content-Type", "application/json")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code: " + response + ", Body: " + Objects.requireNonNull(response.body()).string());
            }

            String responseBody = Objects.requireNonNull(response.body()).string();
            return objectMapper.readValue(responseBody,
                    objectMapper.getTypeFactory().constructParametricType(ApiResponse.class, ContactResp.class));
        }
    }

    /**
     * 创建联系人
     */
    public ApiResponse<ContactResp> createContact(ContactResp contact) throws IOException {
        String jsonBody = objectMapper.writeValueAsString(contact);

        Request request = new Request.Builder()
                .url(BASE_URL + "/contacts")
                .header("Authorization", authorizationHeader)
                .header("Content-Type", "application/json")
                .post(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code: " + response + ", Body: " + Objects.requireNonNull(response.body()).string());
            }

            String responseBody = Objects.requireNonNull(response.body()).string();
            return objectMapper.readValue(responseBody,
                    objectMapper.getTypeFactory().constructParametricType(ApiResponse.class, ContactResp.class));
        }
    }

    /**
     * 更新联系人
     */
    public ApiResponse<ContactResp> updateContact(Integer contactId, ContactResp contact) throws IOException {
        String jsonBody = objectMapper.writeValueAsString(contact);

        Request request = new Request.Builder()
                .url(BASE_URL + "/contacts/" + contactId)
                .header("Authorization", authorizationHeader)
                .header("Content-Type", "application/json")
                .put(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code: " + response + ", Body: " + Objects.requireNonNull(response.body()).string());
            }

            String responseBody = Objects.requireNonNull(response.body()).string();
            return objectMapper.readValue(responseBody,
                    objectMapper.getTypeFactory().constructParametricType(ApiResponse.class, ContactResp.class));
        }
    }


    /**
     * 带分页和过滤条件的获取房源列表
     */
    public ApiResponse<List<EnquiryResp>> getEnquiries(Integer pageNumber, Integer pageSize,
                                                       Map<String, String> filters) throws IOException {
        HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(BASE_URL + "/enquiries")).newBuilder();

        // 添加分页参数
        if (pageNumber != null) {
            urlBuilder.addQueryParameter("page[number]", pageNumber.toString());
        }
        if (pageSize != null) {
            urlBuilder.addQueryParameter("page[size]", pageSize.toString());
        }

        // 添加过滤条件
        if (filters != null) {
            for (Map.Entry<String, String> entry : filters.entrySet()) {
                urlBuilder.addQueryParameter("filter[" + entry.getKey() + "]", entry.getValue());
            }
        }

        Request request = new Request.Builder()
                .url(urlBuilder.build())
                .header("Authorization", authorizationHeader)
                .header("Content-Type", "application/json")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                assert response.body() != null;
                throw new IOException("Unexpected code: " + response + ", Body: " + response.body().string());
            }

            String responseBody = Objects.requireNonNull(response.body()).string();
            return objectMapper.readValue(responseBody,
                    objectMapper.getTypeFactory().constructParametricType(ApiResponse.class,
                            objectMapper.getTypeFactory().constructCollectionType(List.class, EnquiryResp.class)));
        }
    }


    /**
     * 带分页与过滤条件的获取中介列表
     * 过滤示例：filters.put("office_id","358") 、 filters.put("status","current")
     */
    public ApiResponse<List<AgentResp>> getAgents(Integer pageNumber, Integer pageSize,
                                                  Map<String, String> filters) throws IOException {
        HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(BASE_URL + "/agents")).newBuilder();

        if (pageNumber != null) {
            urlBuilder.addQueryParameter("page[number]", pageNumber.toString());
        }
        if (pageSize != null) {
            urlBuilder.addQueryParameter("page[size]", pageSize.toString());
        }
        if (filters != null) {
            for (Map.Entry<String, String> e : filters.entrySet()) {
                urlBuilder.addQueryParameter("filter[" + e.getKey() + "]", e.getValue());
            }
        }

        Request request = new Request.Builder()
                .url(urlBuilder.build())
                .header("Authorization", authorizationHeader)
                .header("Content-Type", "application/json")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code: " + response +
                        ", Body: " + Objects.requireNonNull(response.body()).string());
            }
            String respBody = Objects.requireNonNull(response.body()).string();
            return objectMapper.readValue(respBody,
                    objectMapper.getTypeFactory().constructParametricType(ApiResponse.class,
                            objectMapper.getTypeFactory().constructCollectionType(List.class, AgentResp.class)));
        }
    }

    public void syncDataRecord(Integer count, String type, String status, String name, String errInfo) {
        DataServiceRecord dataServiceRecord = new DataServiceRecord(SnowflakeIdWorker.getSingleton().nextId(),
                name,  nowBeijingDateToSydneyDate(), status, count, errInfo, type);
        dataServiceRecordServiceImpl.save(dataServiceRecord);
    }
}